package com.colin.juc.lock.reentrantlock;

import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by Colin on 2020/4/12 20:12
 * email: colinzhaodong@gmail.com
 * desc: 演示不公平与公平锁
 *
 * @author zhaod
 */
public class FairLock {
	public static void main(String[] args) {
		PrintQueue printQueue = new PrintQueue();
//		ExecutorService threadPoolExecutor = new ThreadPoolExecutor(5, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), (ThreadFactory) Thread::new);
//		for (int i = 0; i <10 ; i++) {
//			threadPoolExecutor.execute(new Job(printQueue));
//		}
//		threadPoolExecutor.shutdown();
		Thread thread[] = new Thread[10];
		for (int i = 0; i < 10; i++) {
			thread[i] = new Thread(new Job(printQueue));
		}
		for (int i = 0; i < 10; i++) {
			thread[i].start();
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Job implements Runnable {

	PrintQueue printQueue;

	public Job(PrintQueue printQueue) {
		this.printQueue = printQueue;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "开始打印");
		printQueue.printJob(new Object());
		System.out.println(Thread.currentThread().getName() + "打印完毕");
	}
}

class PrintQueue {

	private Lock queueLock = new ReentrantLock(false);

	public void printJob(Object document) {
		queueLock.lock();
		try {
			int duration = new Random().nextInt(10) + 1;
			System.out.println(Thread.currentThread().getName() + "正在打印，需要" + duration+"秒");
			Thread.sleep(	duration*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			queueLock.unlock();
		}

		//切换成非公平锁时，由于上面唤醒需要时间，因此下面会马上获取到锁，提高获取效率，减少获取锁的空档时间
		queueLock.lock();
		try {
			int duration = new Random().nextInt(10) + 1;
			System.out.println(Thread.currentThread().getName() + "正在打印，需要" + duration+"秒");
			Thread.sleep(duration*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			queueLock.unlock();
		}
	}
}

